package com.yang.code_sample.performance_count.utils;

import com.yang.code_sample.performance_count.entity.RequestInfo;
import com.yang.code_sample.performance_count.entity.RequestStat;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 *
 * @Description: 根据原始数据，计算得到统计数据, 设计为静态工具类
 * @Author: 杨 强
 * @CreateTime: 2022-10-13 16:33
 */
public class Aggregator {

    /**
     * 统计数据
     * @param requestInfos 需要统计的数据
     * @param durationInMillis 统计的时间范围 -> 持续时间
     * @return 聚合后的统计完成的数据
     */
    public static RequestStat aggregate(List<RequestInfo> requestInfos, long durationInMillis){
        // 最大响应时间
        double maxRespTime = Double.MIN_VALUE;
        // 最小响应时间
        double minRespTime = Double.MAX_VALUE;
        // 平均响应时间
        double avgRespTime = -1;
        double p999RespTime = -1;
        double p99RespTime = -1;
        // 时间和
        double sumRespTime = 0;
        // 请求总次数
        long count = 0;

        // 循环所有的请求数据
        for (RequestInfo requestInfo : requestInfos) {
            // 请求次数+1
            ++count;
            // 该次请求的响应时间
            double responseTime = requestInfo.getResponseTime();
            // 如果最大响应时间小于了当次响应时间,那么就把当次响应时间置为最大响应时间
            if (maxRespTime < responseTime){
                maxRespTime = responseTime;
            }
            if (minRespTime > responseTime){
                minRespTime = responseTime;
            }
            // 总时间
            sumRespTime += responseTime;
        }

        // 计算平均响应时间
        if (count > 0){
            avgRespTime = sumRespTime / count;
        }

        // 计算平均每秒处理的次数
        long tps = count / durationInMillis * 1000;

        // 为请求数据根据响应时间排序
        requestInfos.sort(Comparator.comparingDouble(RequestInfo::getResponseTime));

        // 计算比值
        int idx999 = (int)(count * 0.999);
        int idx99 = (int)(count * 0.99);
        if (count != 0) {
            p999RespTime = requestInfos.get(idx999).getResponseTime();
            p99RespTime = requestInfos.get(idx99).getResponseTime();
        }

        RequestStat requestStat = new RequestStat();
        requestStat.setMaxResponseTime(maxRespTime);
        requestStat.setMinResponseTime(minRespTime);
        requestStat.setAvgResponseTime(avgRespTime);
        requestStat.setP999ResponseTime(p999RespTime);
        requestStat.setP99ResponseTime(p99RespTime);
        requestStat.setCount(count); requestStat.setTps(tps);
        return requestStat;
    }

}
